package cn.itcast.nems.order.web.controller.b;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.itcast.ic.common.bean.Page;
import cn.itcast.ic.common.exception.v2.BizExceptionProducer;
import cn.itcast.ic.common.exception.v2.bean.BizStatusEnum;
import cn.itcast.nems.common.PageQueryModel;
import cn.itcast.nems.common.util.LocalDateTimeUtils;
import cn.itcast.nems.common.web.vo.BasePageRequest;
import cn.itcast.nems.journal.service.JournalDiscountService;
import cn.itcast.nems.manager.util.CustomBeanUtil;
import cn.itcast.nems.order.dto.JournalDiscountApiReqDTO;
import cn.itcast.nems.order.dto.JournalDiscountApiResDTO;
import cn.itcast.nems.order.dto.JournalDiscountDTO;
import cn.itcast.nems.order.dto.JournalDiscountQueryDTO;
import cn.itcast.nems.order.enumeration.QueryRangeType;
import cn.itcast.nems.order.web.util.BusinessApprovalFormWebUtil;
import cn.itcast.nems.order.web.vo.JournalDiscountEditVO;
import cn.itcast.nems.order.web.vo.JournalDiscountQueryVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 优惠凭单相关逻辑
 *
 * @author ChangLu.Gao
 * @version v1.0
 * @program nems-server
 * @description
 * @date 2023/12/08 10:56
 */
@RestController("bjournalDiscountController")
@RequestMapping("/b/journal/discount")
@Slf4j
@RequiredArgsConstructor
public class JournalDiscountController {

    private final JournalDiscountService journalDiscountService;

    /**
     * 优惠单分页查询
     *
     * @param pageRequest 分页查询条件
     * @return org.springframework.http.ResponseEntity<cn.itcast.ic.common.bean.Page < cn.itcast.nems.order.dto.JournalDiscountDTO>>
     * @author 高昌露
     * @since 2023/12/8 11:10
     */
    @PostMapping("/{rangeType}/page/list")
    public ResponseEntity<Page<JournalDiscountDTO>> page(@PathVariable String rangeType, @RequestBody BasePageRequest<JournalDiscountQueryVO> pageRequest) {
        QueryRangeType rangeTypeEnum = QueryRangeType.of(rangeType.toUpperCase());
        Assert.notNull(pageRequest.getCondition(), BizExceptionProducer.badRequest("查询条件不可为空"));
        Assert.notNull(pageRequest.getCondition().getRangeType(), BizExceptionProducer.badRequest(BizStatusEnum.BAD_REQUEST.toString(), "查询条件:%s不可为空", "审批范围"));
        Assert.notNull(pageRequest.getCondition().getMinCreatedDatetime(), BizExceptionProducer.badRequest(BizStatusEnum.BAD_REQUEST.toString(), "查询条件:%s不可为空", "时间范围"));
        Assert.notNull(pageRequest.getCondition().getMaxCreatedDatetime(), BizExceptionProducer.badRequest(BizStatusEnum.BAD_REQUEST.toString(), "查询条件:%s不可为空", "时间范围"));
        pageRequest.convert();
        pageRequest.getCondition().setRangeType(rangeTypeEnum.name());
        PageQueryModel<JournalDiscountQueryDTO> queryModel = new PageQueryModel<>(
                pageRequest.getPageNumber(),
                pageRequest.getPageSize(),
                CustomBeanUtil.copyProperties(pageRequest.getCondition(), new JournalDiscountQueryDTO())
        );
        return ResponseEntity.ok(this.journalDiscountService.pageList(queryModel));
    }

    /**
     * 优惠单保存/编辑
     *
     * @param form 优惠单需要保存/编辑的信息
     * @return org.springframework.http.ResponseEntity<java.lang.String> 优惠凭单ID
     * @author 高昌露
     * @since 2023/12/8 11:11
     */
    @PostMapping("/edit")
    public ResponseEntity<String> saveOrEdit(@RequestBody JournalDiscountEditVO form) {
        Assert.notNull(form, BizExceptionProducer.badRequest("请求数据不可为空"));
        Assert.notNull(form.getDiscountId(), BizExceptionProducer.badRequest("优惠券ID不可为空"));
        Assert.notNull(form.getBusinessLineId(), BizExceptionProducer.badRequest("业务线ID不可为空"));
        Assert.notNull(form.getBusinessLineName(), BizExceptionProducer.badRequest("业务线名称不可为空"));
        Assert.isFalse(CollectionUtil.isNotEmpty(form.getLineList()) && form.getLineList().size() > 500,
                BizExceptionProducer.badRequest("优惠单最大仅支持添加500人!")
        );
        return ResponseEntity.ok(this.journalDiscountService.saveOrEdit(BusinessApprovalFormWebUtil.convert(form)));
    }

    /**
     * 根据凭单ID获取优惠单详情
     *
     * @param id 优惠凭单ID
     * @return org.springframework.http.ResponseEntity<cn.itcast.nems.order.dto.JournalDiscountDTO>
     * @author 高昌露
     * @since 2023/12/8 11:12
     */
    @GetMapping("/detail/{id}")
    public ResponseEntity<JournalDiscountDTO> queryById(@PathVariable String id) {
        return ResponseEntity.ok(this.journalDiscountService.queryById(id));
    }

    /**
     * 根据凭单ID逻辑删除凭单及对应凭单行
     *
     * @param id 凭单ID
     * @return org.springframework.http.ResponseEntity<java.lang.String>
     * @author 高昌露
     * @since 2023/12/8 11:13
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<String> delete(@PathVariable String id) {
        this.journalDiscountService.delete(id);
        return ResponseEntity.ok(id);
    }

    /**
     * 提交工作流
     *
     * @param form 请求参数
     * @return org.springframework.http.ResponseEntity<java.lang.String> 审批单ID
     * @author 高昌露
     * @since 2023/12/8 11:17
     */
    @PostMapping("/commit")
    public ResponseEntity<String> commitToBPM(@RequestBody JournalDiscountEditVO form) {
        Assert.notNull(form, BizExceptionProducer.badRequest("请求数据不可为空"));
        Assert.notNull(form.getId(), BizExceptionProducer.badRequest("凭单ID不可为空"));
        return ResponseEntity.ok(this.journalDiscountService.commitToBPM(form.getId()));
    }

    /**
     * 根据条件获取可用的优惠单
     *
     * @param customerId    客户ID
     * @param studentId     学生ID
     * @param targetClazzId 目标班级ID
     * @param bizDateTime   业务时间
     * @param scenario      业务场景， 升级、转班、学生报名等
     * @return org.springframework.http.ResponseEntity<cn.itcast.nems.order.dto.JournalDiscountDTO>
     * @author 高昌露
     * @since 2023/12/10 16:04
     */
    @GetMapping("/valid")
    public ResponseEntity<List<JournalDiscountApiResDTO>> usableList(
            @RequestParam(name = "customer_id", required = false) String customerId,
            @RequestParam(name = "student_id", required = false) Integer studentId,
            @RequestParam(name = "target_clazz_id") Integer targetClazzId,
            @RequestParam(name = "biz_date_time", required = false) String bizDateTime,
            @RequestParam(name = "scenario", required = false) String scenario
    ) {
        JournalDiscountApiReqDTO.Scenario scenarioEnum = JournalDiscountApiReqDTO.Scenario.of(scenario);
        return ResponseEntity.ok(
                this.journalDiscountService.usableList(
                        JournalDiscountApiReqDTO.buildForUsable(
                                studentId,
                                customerId,
                                targetClazzId,
                                LocalDateTimeUtils.parse(bizDateTime),
                                scenarioEnum
                        )
                )
        );
    }

}
